package com.chen.base.module.mybatis.utils;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.OrderBy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chen.base.module.mybatis.annotation.Like;
import com.chen.base.utils.StreamUtil;
import com.chen.base.utils.basic.MapUtil;
import lombok.SneakyThrows;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: ChenJinLong
 * @DateTime: 2023/9/21 10:36
 **/
public class WrapperUtil {

    /**
     * 根据实体对象构建查询Wrapper，
     * 属性为有效值时，默认eq，属性加上{@link Like}注解可为模糊查询
     * @param entityObj 实体对象
     * @return QueryWrapper
     */
    @SneakyThrows
    public static <T> Wrapper<T> queryWrapperByEntity(T entityObj){
        QueryWrapper<T> wrappers = new QueryWrapper<>();
        List<Map<String, OrderBy>> columnOrderByList = new ArrayList<>();

        for (Field field : entityObj.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            String column = getColumn(field);

            // 如果值为null或者是空串时，则跳过
            Object value = field.get(entityObj);
            if (value != null && StrUtil.isNotBlank(value.toString())){
                boolean isLike = like(wrappers, field, column, value);
                if (!isLike){
                    wrappers.eq(column, value);
                }
            }
            // 顺序
            OrderBy orderBy = field.getAnnotation(OrderBy.class);
            if (orderBy != null){
                columnOrderByList.add(MapUtil.singleMap(column, orderBy));
            }
        }

        orderBy(wrappers, columnOrderByList);
        return wrappers;
    }

    /**
     * 模糊查询
     */
    private static <T> boolean like(QueryWrapper<T> wrappers, Field field,
                                    String column, Object value) {
        // 属性存在Like注解，则需要模糊查询；不存在则eq
        Like like = field.getAnnotation(Like.class);
        if (like != null){
            switch (like.value()){
                case "left":
                    wrappers.likeLeft(column, value);
                    break;
                case "right":
                    wrappers.likeRight(column, value);
                    break;
                default:
                    wrappers.like(column, value);
            }
            return true;
        }
        return false;
    }

    /**
     * 排序
     */
    private static <T> void orderBy(QueryWrapper<T> wrappers, List<Map<String, OrderBy>> columnOrderByList) {
        // 处理排序相关
        List<Map<String, OrderBy>> sort = StreamUtil.sort(columnOrderByList,
                map -> map.get(new ArrayList<>(map.keySet()).get(0)), true
        );
        for (Map<String, OrderBy> orderByMap : sort) {
            String column = MapUtil.getIndexKey(orderByMap, 0);
            OrderBy orderBy = orderByMap.get(column);
            if (orderBy.asc()){
                wrappers.orderByAsc(column);
            }else {
                wrappers.orderByDesc(column);
            }
        }
    }

    /**
     * 获取列名
     */
    public static String getColumn(Field field){
        String column = StrUtil.toUnderlineCase(field.getName());
        // 如果没有以下两个注解，则以实体的属性名为列名
        TableField tableField = field.getAnnotation(TableField.class);
        TableId tableId = field.getAnnotation(TableId.class);

        if (tableField != null && StrUtil.isNotBlank(tableField.value())){
            column = tableField.value();
        }else if (tableId != null){
            if (StrUtil.isNotBlank(tableId.value())){
                column = tableId.value();
            }else {
                column = "id";
            }
        }
        return column;
    }

}
